package com.kingyun.gpsinspection.purificationservice.services.iam.taskjobservice;

import com.kingyun.gpsinspection.purificationservice.dao.mapper.iam.TaskJobInfoMapper;
import com.kingyun.gpsinspection.purificationservice.dao.model.TaskJobInfo;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by yangsy on 2017/3/14.
 */
@Component
//public class TaskJobLoaderListener implements ApplicationListener<ContextRefreshedEvent> {
public class TaskJobLoaderListener {
    private static Logger logger = LoggerFactory.getLogger(TaskJobLoaderListener.class);
    @Autowired
    private TaskJobInfoMapper taskJobInfoMapper;

    //private Scheduler currentScheduler;

    @Autowired(required = false)
    private SchedulerFactoryBean schedulerFactoryBean;

    //@Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        if (contextRefreshedEvent.getApplicationContext().getParent() == null) {
            logger.info("----开始加载定时任务----");
            List<TaskJobInfo> list = this.taskJobInfoList();
            if(list == null || list.size() < 0) return;
            Scheduler scheduler = null;
            scheduler = schedulerFactoryBean.getScheduler(); //getCurrentScheduler();
            int len = list.size();
            for(int i=0;i<len;i++){
                TaskJobInfo taskJobInfo = list.get(i);
                //  对调度表达式进行校验
                boolean validExpression = CronExpression.isValidExpression(taskJobInfo.getTaskJobCorn());
                if(!validExpression){
                    continue;
                }
                try {
                    scheduler =  setScheduler(scheduler,taskJobInfo);
                    scheduler.start();
                }catch (Exception e){
                    e.printStackTrace();
                    logger.error("定时任务加载容器失败:" + e.getMessage());
                }
            }
            logger.info("----加载定时任务结束----");
        }
    }

    //  获取 可用的定时任务数据列表
    protected List<TaskJobInfo> taskJobInfoList (){
        List<TaskJobInfo> list = null;
        try {
            list = taskJobInfoMapper.queryList(new TaskJobInfo());
        }catch (Exception e){
            logger.error("获取定时任务数据失败:" + e.getMessage());
        }
        return list;
    }

/*    protected Scheduler getCurrentScheduler() {
        if(currentScheduler == null){
            //通过SchedulerFactory 获取一个调度器
            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            try {
                currentScheduler = schedulerFactory.getScheduler();
            } catch (SchedulerException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return currentScheduler;
    }*/

    protected  Scheduler setScheduler(Scheduler scheduler,TaskJobInfo taskJobInfo) throws Exception{
        //任务名称和任务组设置规则
        //名称：task_1..
        //组：group_1..
        String taskJobId = taskJobInfo.getTaskjobId();

        TriggerKey triggerKey = TriggerKey.triggerKey("task_"+taskJobId,"group_"+taskJobId);

        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

        //  不存在 则创建一个
        if(trigger == null){
            JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class)
                    .withIdentity("task_"+taskJobId,"group_"+taskJobId).build();
            jobDetail.getJobDataMap().put( "scheduleJob" , taskJobInfo);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
                    .cronSchedule(taskJobInfo.getTaskJobCorn());
            // 按新的表达式构建一个新的trigger
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity( "task_"  + taskJobId,"group_"  + taskJobId)
                    .withSchedule(scheduleBuilder).startNow().build();
            scheduler.scheduleJob(jobDetail, trigger);
        }else{
            // trigger已存在，则更新相应的定时设置
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
                    .cronSchedule(taskJobInfo.getTaskJobCorn());
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(scheduleBuilder).startNow().build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        }
        return scheduler;
    }

}
